home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 2008 September
/
PCWorld_2008-09_cd.bin
/
v cisle
/
sadanastroju
/
autocomplete_manager-2.3-fx.xpi
/
chrome
/
acmanager.jar
/
content
/
options.js
< prev
next >
Wrap
Text File
|
2008-03-14
|
37KB
|
954 lines
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is the Autocomplete Manager extension.
*
* The Initial Developer of the Original Code is
* Nikitas Liogkas <nikitas@acm.org>.
* Portions created by the Initial Developer are Copyright (C) 2005-2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Version: 2.3
*
* ***** END LICENSE BLOCK ***** */
// acmanager.js
// implements all the functionality of the options dialog box
// global Firefox services
const acm_prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
const acm_dateService = Components.classes["@mozilla.org/intl/scriptabledateformat;1"]
.getService(Components.interfaces.nsIScriptableDateFormat);
const acm_mediator = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
// option ids; if you change them here, also change them in default/preferences/acmanager.js
const ACM_ACTIVE_COMPONENT = "extensions.acmanager.active_component";
const ACM_MATCH_BOOKMARKS = "extensions.acmanager.enhanced.match_bookmarks";
const ACM_MATCH_TITLES = "extensions.acmanager.enhanced.match_titles";
const ACM_EXCLUDE_LOCAL = "extensions.acmanager.enhanced.exclude_local";
const ACM_EXCLUDE_SEARCH = "extensions.acmanager.enhanced.exclude_search";
const ACM_MATCH_ALLADDRESS = "extensions.acmanager.enhanced.match_alladdress";
const ACM_MATCH_DOMAIN = "extensions.acmanager.enhanced.match_domain"; // obsolete
const ACM_SORTBY = "extensions.acmanager.enhanced.sortby";
const ACM_SHOW_TITLES = "extensions.acmanager.enhanced.show_titles";
const ACM_SHOW_SOURCE = "extensions.acmanager.enhanced.show_source"; // obsolete
const ACM_SHOW_DATE = "extensions.acmanager.enhanced.show_date";
const ACM_INLINE = "extensions.acmanager.enhanced.inline";
const ACM_SWAP_COLUMNS = "extensions.acmanager.enhanced.swap_columns";
const ACM_BOLD_MATCHING = "extensions.acmanager.enhanced.bold_matching";
const ACM_SHOW_ONARROW = "extensions.acmanager.enhanced.show_onarrow";
const ACM_MAXROWS = "extensions.acmanager.enhanced.maxrows";
const ACM_ADDRESS_TRUNC = "extensions.acmanager.enhanced.address_trunc";
const ACM_TITLE_TRUNC = "extensions.acmanager.enhanced.title_trunc";
const ACM_BOOKMARKS_FIRST = "extensions.acmanager.enhanced.bookmarks_first";
const ACM_DEFAULT_SHOW_TITLES = "extensions.acmanager.default.show_titles";
const ACM_DEFAULT_MATCH_TYPED = "browser.urlbar.matchOnlyTyped";
const ACM_DEFAULT_INLINE = "browser.urlbar.autoFill";
const ACM_DEFAULT_MAXROWS = "extensions.acmanager.default.maxrows";
const ACM_ENHANCED_TABINDEX = "extensions.acmanager.enhanced.tabindex";
// history entry textbox ids; have to match the ones in options.xul
const ACM_HIST_TITLE = "he_title";
const ACM_HIST_ADDRESS = "he_address";
const ACM_HIST_FIRST_VISIT = "he_first_visit";
const ACM_HIST_LAST_VISIT = "he_last_visit";
const ACM_HIST_VISIT_COUNT = "he_visit_count";
// history add entry dialog textbox ids; have to match the ones in addEntry.xul
const ACM_ADD_HIST_TITLE = "add_he_title";
const ACM_ADD_HIST_ADDRESS = "add_he_address";
const ACM_ADD_HIST_FIRST_VISIT = "add_he_first_visit";
const ACM_ADD_HIST_LAST_VISIT = "add_he_last_visit";
const ACM_ADD_HIST_VISIT_COUNT = "add_he_visit_count";
// history edit entry dialog textbox ids; have to match the ones in editDialog.xul
//const ACM_EDIT_HIST_TITLE = "edit_he_title";
//const ACM_EDIT_HIST_ADDRESS = "edit_he_address";
//const ACM_EDIT_HIST_FIRST_VISIT = "edit_he_first_visit";
//const ACM_EDIT_HIST_LAST_VISIT = "edit_he_last_visit";
//const ACM_EDIT_HIST_VISIT_COUNT = "edit_he_visit_count";
// variables to record preferences for use in acm_enforcePreferences();
// also used when filtering candidates
var acm_active_component, acm_match_bookmarks, acm_match_titles, acm_exclude_local,
acm_exclude_search, acm_match_alladdress;
// AutocompleteCandidate object arrays
var acm_history = []; // all displayed items
var acm_addedHistEntries = []; // new entries added during this invocation of options dialog
var acm_editedHistEntries = []; // existing entries with modified content
var acm_deletedHistEntries = []; // existing entries to be deleted
var acm_editedURLs = []; // modified URLs of old entries that have been edited
var acm_addedEntryIndex; // is an entry new?
var acm_editedEntryIndex; // has an entry been edited?
// history tree
var acm_treeHistory = null;
// for the column sorting of the history tree
var acm_histSortCriterion = "URL";
var acm_histSortDirection = false; // 'true' for ascending, 'false' for descending
// the custom view for the history tree
var acm_treeHistoryView =
{
rowCount : 0,
cycleHeader: function(column) { },
getCellText : function(row, column)
{
var text = "";
if (column.id === "colURL")
text = acm_history[row].URL;
else if (column.id === "coltitle")
text = acm_history[row].title;
return text;
},
getImageSrc : function(row, column){ return null; },
getRowProperties : function(row, props){ },
getCellProperties : function(row, column, properties) { },
getColumnProperties : function(colid, col, props) { },
isContainer : function(index) { return false; },
isEditable : function(row, column) { return false; },
isSeparator : function(index) { return false; },
isSorted : function(row) { return false; },
setCellText : function(row, column, value) { },
setTree: function() { }
};
// returns the specified preference
function acm_getPreference(pref_name)
{
var pref_type = acm_prefs.getPrefType(pref_name);
if (pref_type === acm_prefs.PREF_STRING)
return acm_prefs.getCharPref(pref_name);
else if (pref_type === acm_prefs.PREF_INT)
return acm_prefs.getIntPref(pref_name);
else if (pref_type === acm_prefs.PREF_BOOL)
return acm_prefs.getBoolPref(pref_name);
else // fallback on error
return acm_prefs.PREF_INVALID;
}
// records preferences for later use in acm_enforcePreferences()
function acm_recordPreferences()
{
acm_active_component = acm_getPreference(ACM_ACTIVE_COMPONENT);
acm_match_bookmarks = acm_getPreference(ACM_MATCH_BOOKMARKS);
acm_match_titles = acm_getPreference(ACM_MATCH_TITLES);
acm_exclude_local = acm_getPreference(ACM_EXCLUDE_LOCAL);
acm_exclude_search = acm_getPreference(ACM_EXCLUDE_SEARCH);
acm_match_alladdress = acm_getPreference(ACM_MATCH_ALLADDRESS);
// restore the previously selected tab
document.getElementById("acm_tabbox").selectedIndex = acm_getPreference(ACM_ENHANCED_TABINDEX);
}
// updates the dependencies for the UI elements
function acm_updateUIDependencies()
{
// disable the corresponding groupbox of options, based on which component is enabled;
// NOTE: the following doesn't work!?
// var component_radios = document.getElementById(ACM_ACTIVE_COMPONENT).childNodes;
if (document.getElementById("acm_enhanced_radio").selected) {
acm_setEnhancedOptions(true);
acm_setDefaultOptions(false);
}
else if (document.getElementById("acm_default_radio").selected) {
acm_setEnhancedOptions(false);
acm_setDefaultOptions(true);
}
else {
acm_setEnhancedOptions(false);
acm_setDefaultOptions(false);
}
}
// enables/disables the bookmarks position radiogroup
function acm_setBookmarksPosition()
{
// NOTE: right after the user clicked on the checkbox,
// 'document.getElementById(ACM_MATCH_BOOKMARKS).value' gives
// us the old value of the checkbox (before the click)
if (document.getElementById(ACM_MATCH_BOOKMARKS).value)
document.getElementById(ACM_BOOKMARKS_FIRST).disabled = true;
else
document.getElementById(ACM_BOOKMARKS_FIRST).disabled = false;
}
// enables/disables the swap columns option
function acm_setSwapColumns()
{
if (document.getElementById(ACM_SHOW_TITLES).value)
document.getElementById(ACM_SWAP_COLUMNS).disabled = true;
else
document.getElementById(ACM_SWAP_COLUMNS).disabled = false;
}
// enables/disables the options that pertain to the enhanced component
function acm_setEnhancedOptions(flag)
{
document.getElementById(ACM_MATCH_BOOKMARKS).disabled = !flag;
document.getElementById(ACM_MATCH_TITLES).disabled = !flag;
document.getElementById(ACM_EXCLUDE_LOCAL).disabled = !flag;
document.getElementById(ACM_EXCLUDE_SEARCH).disabled = !flag;
document.getElementById(ACM_MATCH_ALLADDRESS).disabled = !flag;
document.getElementById(ACM_SORTBY).disabled = !flag;
document.getElementById(ACM_ADDRESS_TRUNC).disabled = !flag;
document.getElementById(ACM_TITLE_TRUNC).disabled = !flag;
document.getElementById(ACM_SHOW_TITLES).disabled = !flag;
document.getElementById(ACM_SHOW_DATE).disabled = !flag;
document.getElementById(ACM_INLINE).disabled = !flag;
document.getElementById(ACM_SWAP_COLUMNS).disabled = !flag;
document.getElementById(ACM_BOLD_MATCHING).disabled = !flag;
document.getElementById(ACM_SHOW_ONARROW).disabled = !flag;
document.getElementById(ACM_MAXROWS).disabled = !flag;
// NOTE: 'document.getElementById(ACM_MATCH_BOOKMARKS).checked' doesn't work!?
if (flag && document.getElementById(ACM_MATCH_BOOKMARKS).value)
document.getElementById(ACM_BOOKMARKS_FIRST).disabled = false;
else
document.getElementById(ACM_BOOKMARKS_FIRST).disabled = true;
// disable swap columns option if page titles are not to be shown
if (flag && document.getElementById(ACM_SHOW_TITLES).value)
document.getElementById(ACM_SWAP_COLUMNS).disabled = false;
else
document.getElementById(ACM_SWAP_COLUMNS).disabled = true;
}
// enables/disables the options that pertain to the default component
function acm_setDefaultOptions(flag)
{
document.getElementById(ACM_DEFAULT_SHOW_TITLES).disabled = !flag;
document.getElementById(ACM_DEFAULT_MATCH_TYPED).disabled = !flag;
document.getElementById(ACM_DEFAULT_INLINE).disabled = !flag;
document.getElementById(ACM_DEFAULT_MAXROWS).disabled = !flag;
}
// validates the user-input values for the number of visible suggestions
function acm_validateMaxrowsValues()
{
// custom component
var cust_textbox = document.getElementById(ACM_MAXROWS);
var custom_maxrows_entered = window.parseInt(cust_textbox.value, 10);
if (custom_maxrows_entered <= 1) {
alert("The number of visible suggestions has to be greater than one!");
cust_textbox.value = acm_getPreference(ACM_MAXROWS);
}
// default component
var default_textbox = document.getElementById(ACM_DEFAULT_MAXROWS);
if (default_textbox.value <= 1) {
alert("The number of visible suggestions has to be greater than one!");
default_textbox.value = acm_getPreference(ACM_DEFAULT_MAXROWS, "int");
}
}
// enforces user preferences when the options dialog is closed
function acm_enforcePreferences()
{
this.setCursor("wait");
// any browser window will do
var browserWindow = acm_mediator.getMostRecentWindow("navigator:browser");
// save selected tab in enhanced options
acm_prefs.setIntPref(ACM_ENHANCED_TABINDEX, document.getElementById("acm_tabbox").selectedIndex);
if (document.getElementById("acm_enhanced_radio").selected) {
// add history items and/or bookmarks if they hadn't been added before
if (acm_active_component !== "enhanced") {
if (!browserWindow.acm_Aggregator.includedEntries[ACM_SOURCE_HISTORY])
browserWindow.acm_Aggregator.addHistoryEntries();
else if (document.getElementById(ACM_MATCH_BOOKMARKS).value
&& !browserWindow.acm_Aggregator.includedEntries[ACM_SOURCE_BOOKMARKS])
browserWindow.acm_Aggregator.addBookmarks();
}
// include/exclude bookmarks (invalidates caches)
if (acm_match_bookmarks && !document.getElementById(ACM_MATCH_BOOKMARKS).value) {
if (browserWindow.acm_Aggregator.includedEntries[ACM_SOURCE_BOOKMARKS])
browserWindow.acm_Aggregator.removeBookmarks();
}
else if (!acm_match_bookmarks && document.getElementById(ACM_MATCH_BOOKMARKS).value) {
if (!browserWindow.acm_Aggregator.includedEntries[ACM_SOURCE_BOOKMARKS])
browserWindow.acm_Aggregator.addBookmarks();
}
// invalidate caches if there is any difference in the candidate selection options
var titles_choice = document.getElementById(ACM_MATCH_TITLES).value;
var local_choice = document.getElementById(ACM_EXCLUDE_LOCAL).value;
var search_choice = document.getElementById(ACM_EXCLUDE_SEARCH).value;
var alladdress_choice = document.getElementById(ACM_MATCH_ALLADDRESS).value;
if (acm_match_titles !== titles_choice || acm_exclude_local !== local_choice
|| acm_exclude_search !== search_choice || acm_match_alladdress !== alladdress_choice)
acm_invalidateCaches();
// set acm_maxrows for all open browser windows
var custom_maxrows_entered = window.parseInt(document.getElementById(ACM_MAXROWS).value, 10);
var browser_windows = acm_mediator.getEnumerator("navigator:browser");
while (browser_windows.hasMoreElements())
browser_windows.getNext().acm_maxrows = custom_maxrows_entered;
}
// set the appropriate location bar for all open browser windows
var browser_windows = acm_mediator.getEnumerator("navigator:browser");
var urlbar;
while (browser_windows.hasMoreElements()) {
var nextWindow = browser_windows.getNext();
if (document.getElementById("acm_default_radio").selected) {
// set default urlbar's properties
urlbar = nextWindow.document.getElementById("urlbar");
urlbar.setAttribute("showcommentcolumn", document.getElementById(ACM_DEFAULT_SHOW_TITLES).value);
urlbar.setAttribute("maxrows", window.parseInt(document.getElementById(ACM_DEFAULT_MAXROWS).value, 10));
// remove enhanced urlbar's properties
if (acm_active_component !== "default")
nextWindow.acm_removeEnhancedUrlbarProperties();
}
else {
urlbar = nextWindow.document.getElementById("urlbar");
urlbar.removeAttribute("showcommentcolumn");
urlbar.removeAttribute("maxrows");
if (acm_active_component === "default")
nextWindow.acm_addEnhancedUrlbarProperties();
}
}
// the options dialog has been unloaded
acm_active_component = null;
// update history file with added, edited, and removed entries;
// NOTE: preserve this order to avoid incorrect entry removal from the aggregator; see acm_onEditOK()
acm_removeDeletedHistEntries();
//acm_updateEditedHistEntries();
acm_addNewHistEntries();
this.setCursor("auto");
}
// populates the history tree with all history entries
function acm_populateHistoryEntries()
{
// check if we can get them from acm_Aggregator
if (acm_active_component !== "enhanced") {
var getthem = confirm("Retrieving history entries may take some time, depending on the size of \
your history file. If you get a warning about an unresponsive script, just click 'Continue'.\nClick \
'OK' to retrieve your history entries.");
if (!getthem)
return;
this.setCursor("wait");
document.getElementById("populateHistEntries").disabled = true;
acm_entryGenerator = acm_getHistoryItems();
var nextEntry;
while (true) {
nextEntry = acm_entryGenerator.next();
if (nextEntry !== null)
acm_history.push(nextEntry);
else
break;
}
}
else {
this.setCursor("wait");
document.getElementById("populateHistEntries").disabled = true;
// any browser window will do
var browserWindow = acm_mediator.getMostRecentWindow("navigator:browser");
acm_history = browserWindow.acm_Aggregator.allCandidates;
// remove bookmarks if they had been added, and add history duplicates
if (acm_match_bookmarks) {
// start from the end of the array for splice to work properly
for (var i = acm_history.length - 1; i >= 0; i--) {
if (acm_history[i].source === ACM_SOURCE_BOOKMARKS)
acm_history.splice(i, 1);
}
acm_history = acm_history.concat(browserWindow.acm_Aggregator.dups);
}
}
if (!acm_treeHistory)
acm_treeHistory = document.getElementById("acm_historyTree");
acm_treeHistoryView.rowCount = acm_history.length;
acm_treeHistory.treeBoxObject.view = acm_treeHistoryView;
document.getElementById("addHistoryEntry").disabled = false;
if (acm_history.length > 0)
document.getElementById("removeAllHistoryEntries").disabled = false;
// NOTE: functional dependency; do this after enabling the buttons
acm_sortHistoryColumn("URL");
this.setCursor("auto");
}
// sorts history entries according to the given AutocompleteCandidate field,
// while maintaining the current tree selection
function acm_sortHistoryColumn(criterion)
{
// return if the tree has not been filled yet
if (!document.getElementById("populateHistEntries").disabled)
return;
this.setCursor("wait");
// find the new and previous sorting columns
var colNewID = (criterion === "URL") ? "colURL" : "coltitle";
var colPreviousID = (acm_histSortCriterion === "URL") ? "colURL" : "coltitle";
var colNew = acm_treeHistory.columns[colNewID].element;
var colPrevious = acm_treeHistory.columns[colPreviousID].element;
// sort the tree; first time we sort by a column, it is ascending; reverse the sorting for the same column
acm_histSortDirection = (criterion === acm_histSortCriterion) ? !acm_histSortDirection : true;
acm_histSortCriterion = criterion;
acm_sortHistoryTree();
// set the sorting indicator
var direction = acm_histSortDirection ? "ascending" : "descending";
if (colNew === colPrevious)
colNew.setAttribute("sortDirection", direction);
else {
colPrevious.removeAttribute("sortDirection");
colNew.setAttribute("sortDirection", direction);
}
this.setCursor("auto");
}
// handles key events on the history tree
function acm_handleKey(event)
{
// Del was pressed
if (event.keyCode === event.DOM_VK_DELETE)
acm_removeHistoryEntry();
}
// displays the available information for the selected history entry
function acm_historyEntrySelected()
{
// if an entry was selected, and we click on Remove All, the selection remains!
if (!acm_history.length)
return;
var selections = acm_getTreeSelections(acm_treeHistory);
// if an entry was selected, enable the Edit and Remove buttons, else clear the information box
if (selections.length === 1) {
//document.getElementById("editHistoryEntry").disabled = false;
document.getElementById("removeHistoryEntry").disabled = false;
}
else if (selections.length > 1) {
//document.getElementById("editHistoryEntry").disabled = true;
document.getElementById("removeHistoryEntry").disabled = false;
}
else
acm_clearHistInfoBox();
// clear the information box if multiple entries are selected
if (selections.length > 1) {
acm_clearHistInfoBox();
return;
}
var index = selections[0];
// associate textboxes with AutocompleteCandidate fields
var hist_textbox_props =
[
{id: ACM_HIST_TITLE, value: acm_history[index].title},
{id: ACM_HIST_ADDRESS, value: acm_history[index].URL},
{id: ACM_HIST_FIRST_VISIT, value: acm_history[index].first_visit},
{id: ACM_HIST_LAST_VISIT, value: acm_history[index].last_visit},
{id: ACM_HIST_VISIT_COUNT, value: acm_history[index].visit_count}
];
// update the values of the textboxes
var textbox;
for (var i = 0, len = hist_textbox_props.length; i < len; i++) {
var id = hist_textbox_props[i].id;
textbox = document.getElementById(id);
if ( (id === ACM_HIST_FIRST_VISIT) || (id === ACM_HIST_LAST_VISIT) )
textbox.value = acm_micros2date(hist_textbox_props[i].value);
else
textbox.value = hist_textbox_props[i].value;
}
}
// clears the history information box
function acm_clearHistInfoBox()
{
document.getElementById(ACM_HIST_TITLE).value = "";
document.getElementById(ACM_HIST_ADDRESS).value = "";
document.getElementById(ACM_HIST_FIRST_VISIT).value = "";
document.getElementById(ACM_HIST_LAST_VISIT).value = "";
document.getElementById(ACM_HIST_VISIT_COUNT).value = "";
}
// converts microsecs to a formatted date
function acm_micros2date(microsecs)
{
if (window.isNaN(microsecs) || (microsecs === 0))
return "";
else {
var d = new Date(microsecs/1000);
return acm_dateService.FormatDateTime(
"", acm_dateService.dateFormatShort,
acm_dateService.timeFormatNoSecondsForce24Hour,
d.getFullYear(), d.getMonth() + 1, // month is 1-12
d.getDate(), d.getHours(),
d.getMinutes(), d.getSeconds());
}
}
// converts a formatted date to microseconds; returns NaN if the dateString is malformed
function acm_date2micros(dateString)
{
var d = new Date(dateString);
d.setMonth(d.getMonth() + 1); // month is 1-12
return Date.parse(d.toLocaleString()) * 1000;
}
// saves the new entry that was input by the user in the Add History Entry dialog box
function acm_onAddOK()
{
this.setCursor("wait");
// get user input
var title = document.getElementById(ACM_ADD_HIST_TITLE).value;
var address = document.getElementById(ACM_ADD_HIST_ADDRESS).value;
//var firstvisit = acm_date2micros(document.getElementById(ACM_ADD_HIST_FIRST_VISIT).value);
//var lastvisit = acm_date2micros(document.getElementById(ACM_ADD_HIST_LAST_VISIT).value);
//var visitcount = window.parseInt(document.getElementById(ACM_ADD_HIST_VISIT_COUNT).value, 10);
// set new entry properties
if (!address) {
alert("You have to specify an address!");
return;
}
var protocolSpecified = (address.search("^[a-z]*://") !== -1)
if (!protocolSpecified)
address = "http://" + address;
//if (window.isNaN(firstvisit)) {
// if (document.getElementById(ACM_ADD_HIST_FIRST_VISIT).value)
// alert("First Visit Date is malformed!");
// firstvisit = 0;
//}
//if (window.isNaN(lastvisit)) {
// if (document.getElementById(ACM_ADD_HIST_LAST_VISIT).value)
// alert("Last Visit Date is malformed!");
// lastvisit = 0;
//}
//if (window.isNaN(visitcount)) {
// if (document.getElementById(ACM_ADD_HIST_VISIT_COUNT).value)
// alert("Visit Count is invalid!");
// visitcount = 0;
//}
//var newEntry = new AutocompleteCandidate(opener.acm_history.length, title, address,
// firstvisit, lastvisit, visitcount, ACM_SOURCE_HISTORY);
var newEntry = new AutocompleteCandidate(opener.acm_history.length, title, address,
0, 0, "", 0, null, ACM_SOURCE_HISTORY);
opener.acm_addedHistEntries.push(newEntry);
// insert at the correct position in the tree
var rowChanged; // the first of two rows we are going to change
if (!opener.acm_history.length) { // empty history file
opener.acm_history.push(newEntry);
rowChanged = 0;
}
else {
// place at the beginning of array
if (acm_alphaHistorySortFun(newEntry, opener.acm_history[0]) <= 0) {
opener.acm_history.splice(0, 1, newEntry, opener.acm_history[0]);
rowChanged = 0;
}
// place at the end of array
else if (acm_alphaHistorySortFun(newEntry, opener.acm_history[opener.acm_history.length - 1]) >= 0) {
opener.acm_history.splice(opener.acm_history.length - 1, 1,
opener.acm_history[opener.acm_history.length - 1], newEntry);
rowChanged = opener.acm_history.length - 2;
}
// place in the middle
else {
for (var i = 0; i <= opener.acm_history.length - 2; i++) {
if (acm_alphaHistorySortFun(newEntry, opener.acm_history[i]) >= 0
&& acm_alphaHistorySortFun(newEntry, opener.acm_history[i+1]) <= 0) {
opener.acm_history.splice(i, 1, opener.acm_history[i], newEntry);
rowChanged = i;
break;
}
}
}
}
// enable buttons
//opener.document.getElementById("editHistoryEntry").disabled = false;
opener.document.getElementById("removeHistoryEntry").disabled = false;
opener.document.getElementById("removeAllHistoryEntries").disabled = false;
// add new entry to the history tree
opener.acm_treeHistory.view.selection.selectEventsSuppressed = true;
opener.acm_treeHistoryView.rowCount += 1;
if (acm_history.length) {
opener.acm_treeHistory.treeBoxObject.rowCountChanged(rowChanged, -1);
opener.acm_treeHistory.treeBoxObject.rowCountChanged(rowChanged, 2);
}
else
opener.acm_treeHistory.treeBoxObject.rowCountChanged(rowChanged, 1);
var rowNewItem = (rowChanged === 0) ? 0 : rowChanged + 1;
opener.acm_treeHistory.treeBoxObject.ensureRowIsVisible(rowNewItem);
opener.acm_treeHistory.view.selection.select(rowNewItem);
opener.acm_treeHistory.view.selection.selectEventsSuppressed = false;
this.setCursor("auto");
}
// fills in the relevant information in the Edit Entry dialog box
function acm_setupEditDialog()
{
var selections = acm_getTreeSelections(opener.document.getElementById("acm_historyTree"));
// only one entry should be selected when we get here
if (selections.length > 1) {
alert("More than one entry is selected!");
return;
}
var index = selections[0];
// associate textboxes with AutocompleteCandidate fields
var edit_hist_textbox_props =
[
{id: ACM_EDIT_HIST_TITLE, value: opener.acm_history[index].title},
{id: ACM_EDIT_HIST_ADDRESS, value: opener.acm_history[index].URL},
{id: ACM_EDIT_HIST_FIRST_VISIT, value: opener.acm_history[index].first_visit},
{id: ACM_EDIT_HIST_LAST_VISIT, value: opener.acm_history[index].last_visit},
{id: ACM_EDIT_HIST_VISIT_COUNT, value: opener.acm_history[index].visit_count}
];
// update the values of the textboxes
var textbox;
for (var i = 0, len = edit_hist_textbox_props.length; i < len; i++) {
var id = edit_hist_textbox_props[i].id;
textbox = document.getElementById(id);
if ( (id === ACM_EDIT_HIST_FIRST_VISIT) || (id === ACM_EDIT_HIST_LAST_VISIT) )
textbox.value = acm_micros2date(edit_hist_textbox_props[i].value)
else
textbox.value = edit_hist_textbox_props[i].value;
}
// check if this is a newly added entry
acm_addedEntryIndex = -1;
for (var i = 0, len = opener.acm_addedHistEntries.length; i < len; i++) {
if (opener.acm_addedHistEntries[i].URL === opener.acm_history[index].URL) {
acm_addedEntryIndex = i;
break;
}
}
// check if this is an edited entry
acm_editedEntryIndex = -1;
for (var i = 0, len = opener.acm_editedHistEntries.length; i < len; i++) {
if (opener.acm_editedHistEntries[i].URL === opener.acm_history[index].URL) {
acm_editedEntryIndex = i;
break;
}
}
}
// saves the changes that were input by the user in the Edit Entry dialog box
function acm_onEditOK()
{
var selections = acm_getTreeSelections(opener.document.getElementById("acm_historyTree"));
var index = selections[0];
var textbox;
textbox = document.getElementById(ACM_EDIT_HIST_ADDRESS);
if (!textbox.value) {
alert("You have to at least specify the address!");
return;
}
// update entry properties
var protocolSpecified = (textbox.value.search("^[a-z]*://") !== -1)
var newURL;
if (protocolSpecified)
newURL = textbox.value;
else
newURL = "http://" + textbox.value;
// save old URL to remove it from the aggregator list later
var oldURL = null;
if (newURL !== opener.acm_history[index].URL)
oldURL = opener.acm_history[index].URL;
opener.acm_history[index].URL = newURL;
textbox = document.getElementById(ACM_EDIT_HIST_TITLE);
opener.acm_history[index].title = textbox.value;
textbox = document.getElementById(ACM_EDIT_HIST_FIRST_VISIT);
var firstvisit = acm_date2micros(textbox.value);
if (window.isNaN(firstvisit)) {
if (textbox.value)
alert("First Visit Date is malformed!");
}
else
opener.acm_history[index].first_visit = firstvisit;
textbox = document.getElementById(ACM_EDIT_HIST_LAST_VISIT);
var lastvisit = acm_date2micros(textbox.value);
if (window.isNaN(lastvisit)) {
if (textbox.value)
alert("Last Visit Date is malformed!");
}
else
opener.acm_history[index].last_visit = lastvisit;
textbox = document.getElementById(ACM_EDIT_HIST_VISIT_COUNT);
var visitcount = window.parseInt(textbox.value, 10);
if (window.isNaN(visitcount)) {
if (textbox.value)
alert("Visit Count is invalid!");
}
else
opener.acm_history[index].visit_count = visitcount;
// remove the edited entry from the main array
var newEntry = opener.acm_history[index];
opener.acm_history.splice(index, 1);
// insert at the correct position in the tree
var rowChanged = -1; // first of the two rows we are going to change
if (opener.acm_histSortDirection) {
// place at the beginning of array
if (newEntry[opener.acm_histSortCriterion] <= opener.acm_history[0][opener.acm_histSortCriterion]) {
opener.acm_history.splice(0, 1, newEntry, opener.acm_history[0]);
rowChanged = 0;
}
// place at the end of array
if (newEntry[opener.acm_histSortCriterion] >=
opener.acm_history[opener.acm_history.length - 1][opener.acm_histSortCriterion]) {
opener.acm_history.splice(opener.acm_history.length - 1, 1, opener.acm_history[0], newEntry);
rowChanged = opener.acm_history.length;
}
if (rowChanged === -1) {
for (var i = 0; i <= opener.acm_history.length - 2; i++) {
if ( (newEntry[opener.acm_histSortCriterion] >= opener.acm_history[i][opener.acm_histSortCriterion])
&& (newEntry[opener.acm_histSortCriterion] <= opener.acm_history[i+1][opener.acm_histSortCriterion]) ) {
opener.acm_history.splice(i, 1, opener.acm_history[i], newEntry);
rowChanged = i;
break;
}
}
}
}
else
{
// place at the beginning of array
if (newEntry[opener.acm_histSortCriterion] >= opener.acm_history[0][opener.acm_histSortCriterion]) {
opener.acm_history.splice(0, 1, newEntry, opener.acm_history[0]);
rowChanged = 0;
}
// place at the end of array
if (newEntry[opener.acm_histSortCriterion] <=
opener.acm_history[opener.acm_history.length - 1][opener.acm_histSortCriterion]) {
opener.acm_history.splice(opener.acm_history.length - 1, 1, opener.acm_history[0], newEntry);
rowChanged = opener.acm_history.length;
}
if (rowChanged === -1) {
for (var i = 0; i <= opener.acm_history.length - 2; i++) {
if ( (newEntry[opener.acm_histSortCriterion] <= opener.acm_history[i][opener.acm_histSortCriterion])
&& (newEntry[opener.acm_histSortCriterion] >= opener.acm_history[i+1][opener.acm_histSortCriterion]) ) {
opener.acm_history.splice(i, 1, opener.acm_history[i], newEntry);
rowChanged = i;
break;
}
}
}
}
// add to the appropriate array
if (acm_addedEntryIndex === -1) { // old entry
if (acm_editedEntryIndex === -1) { // not an already edited entry
opener.acm_editedHistEntries.push(newEntry);
if (oldURL) // URL has been modified
opener.acm_editedURLs.push(oldURL);
}
else { // edited entry
opener.acm_editedHistEntries.splice(acm_editedEntryIndex, 1);
opener.acm_editedHistEntries.push(newEntry);
// URL has been modified; normally we should remove the old oldURL,
// to avoid incorrect removal of that URL from the aggregator; nevertheless,
// this is taken care of if we preserve the order of write-back
// calls in acm_onOK(), since the URL will be eventually added if necessary!
if (oldURL)
opener.acm_editedURLs.push(oldURL);
}
}
else { // new entry
opener.acm_addedEntries.splice(acm_addedEntryIndex, 1);
opener.acm_addedHistEntries.push(newEntry);
}
// update the tree view
var rowNewItem = (rowChanged === 0) ? 0 : rowChanged + 1;
opener.acm_treeHistory.view.selection.select(0);
opener.acm_treeHistory.view.selection.select(rowNewItem); // reselect to update info box
opener.acm_treeHistory.treeBoxObject.ensureRowIsVisible(rowNewItem);
}
// removes selected history entries
function acm_removeHistoryEntry()
{
// disable tree selection notifications during the deletion
acm_treeHistory.view.selection.selectEventsSuppressed = true;
// place deleted items into deletedHistEntries array, and set them to null in the acm_history array
var selections = acm_getTreeSelections(acm_treeHistory);
for (var i = selections.length - 1; i >= 0; i--) {
// check if this is a newly-added entry
acm_addedEntryIndex = -1;
for (var j = 0, len = acm_addedHistEntries.length; j < len; j++) {
if (acm_addedHistEntries[j].URL === acm_history[selections[i]].URL) {
acm_addedEntryIndex = j;
break;
}
}
// check if this is an edited entry
acm_editedEntryIndex = -1;
//for (var j = 0, len = acm_editedHistEntries.length; j < len; j++) {
// if (acm_editedHistEntries[j].URL === acm_history[selections[i]].URL) {
// acm_editedEntryIndex = j;
// break;
// }
//}
// add to the appropriate array
if (acm_addedEntryIndex === -1) { // old entry
if (acm_editedEntryIndex === -1) // not an already-edited entry
acm_deletedHistEntries.push(acm_history[selections[i]]);
else { // edited entry
acm_editedHistEntries.splice(acm_editedEntryIndex, 1);
acm_deletedHistEntries.push(acm_history[selections[i]]);
}
}
else // new entry
acm_addedHistEntries.splice(acm_addedEntryIndex, 1);
acm_history[selections[i]] = null;
}
// clean up original array by removing all the null entries
for (var tail = acm_history.length - 1; tail >= 0; tail--) {
if (acm_history[tail] === null) {
var head = tail; // find consecutive deleted selections
while ( (head >= 0) && (acm_history[head] === null) )
head--;
acm_history.splice(head + 1, tail - head);
acm_treeHistoryView.rowCount -= (tail - head);
acm_treeHistory.treeBoxObject.rowCountChanged(head + 1, head - tail);
}
}
// update selection or buttons
if (acm_history.length) {
// update selection and tree view
var nextEntry = (selections[0] < acm_history.length) ?
selections[0] : acm_history.length - 1;
acm_treeHistory.view.selection.select(nextEntry);
acm_treeHistory.treeBoxObject.ensureRowIsVisible(nextEntry);
}
else {
// disable buttons
//document.getElementById("editHistoryEntry").disabled = true;
document.getElementById("removeHistoryEntry").disabled = true;
document.getElementById("removeAllHistoryEntries").disabled = true;
acm_clearHistInfoBox();
}
// reenable tree selection notifications after the deletion
acm_treeHistory.view.selection.selectEventsSuppressed = false;
}
// removes all history entries
function acm_removeAllHistEntries()
{
var answer = confirm("Are you sure you want to remove all history entries?")
if (answer) {
for (var i = 0, lenHistory = acm_history.length; i < lenHistory; i++) {
// check if this is a newly-added entry
acm_addedEntryIndex = -1;
for (var j = 0, lenAddedEntries = acm_addedHistEntries.length; j < lenAddedEntries; j++) {
if (acm_addedHistEntries[j].URL === acm_history[i].URL) {
acm_addedEntryIndex = j;
break;
}
}
// only mark old entries for deletion
if (acm_addedEntryIndex === -1)
acm_deletedHistEntries.push(acm_history[i]);
}
// clear arrays
acm_addedHistEntries = [];
//acm_editedHistEntries = [];
//acm_editedURLs = [];
acm_history = [];
// update the tree view
var oldCount = acm_treeHistoryView.rowCount;
acm_treeHistoryView.rowCount = 0;
acm_treeHistory.treeBoxObject.rowCountChanged(0, -oldCount);
// disable buttons
//document.getElementById("editHistoryEntry").disabled = true;
document.getElementById("removeHistoryEntry").disabled = true;
document.getElementById("removeAllHistoryEntries").disabled = true;
acm_clearHistInfoBox();
}
}